home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Random / Commodore 64c / SOURCE / Instructions.c < prev    next >
Text File  |  1994-02-27  |  11KB  |  338 lines

  1. /*
  2.     Commodore 64 Emulator v0.1      Earle F. Philhower III 
  3.     Copyright (C) 1993-4            (st916w9r@dunx1.ocs.drexel.edu)
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "Registers.h"
  20. #include "Flags.h"
  21. #include "Instructions.h"
  22. #include "Stack.h"
  23. #include "Modes.h"
  24. #include "Memory.h"
  25. #include "Vectors.h"
  26.  
  27. void i00() {
  28.     PushWord(pc);
  29.     flags |= BKC;
  30.     Push(flags);
  31.     flags &= ~BKC;
  32.     pc=WordAt(IrqTo); }
  33. void i01() { ORA(IndirectXAddr); pc++; }
  34. void i05() { ORA(ZeroPageAddr); pc++; }
  35. void i06() { ASL(ZeroPageAddr); pc++; }
  36. void i08() { Push(flags); }
  37. void i09() { a |= ImmediateByte(); FlagsNZ(a); pc++; }
  38. void i0a() {
  39.     if (a&128) flags |= CAR;
  40.     else flags &= ~CAR;
  41.     a=a<<1;
  42.     FlagsNZ(a); }
  43. void i0d() { ORA(AbsoluteAddr); pc+=2; }
  44. void i0e() { ASL(AbsoluteAddr); pc+=2; }
  45. void i10() { BCL(NEG); }
  46. void i11() { ORA(IndirectYAddr); pc++; }
  47. void i15() { ORA(ZeroPageXAddr); pc++; }
  48. void i16() { ASL(ZeroPageXAddr); pc++; }
  49. void i18() { CLR(CAR); }
  50. void i19() { ORA(AbsoluteYAddr); pc+=2; }
  51. void i1d() { ORA(AbsoluteXAddr); pc+=2; }
  52. void i1e() { ASL(AbsoluteXAddr); pc+=2; }
  53. void i20() { PushWord(pc+1); pc=WordAt(pc); }
  54. void i21() { AND(IndirectXAddr); pc++; }
  55. void i24() { BIT(ZeroPageAddr); pc++; }
  56. void i25() { AND(ZeroPageAddr); pc++; }
  57. void i26() { ROL(ZeroPageAddr); pc++; }
  58. void i28() { flags = Pop(); }
  59. void i29() { a &= ImmediateByte(); FlagsNZ(a); pc++; }
  60. void i2a() {
  61.     if (flags&CAR) {
  62.         if ((a&128)==0) flags &=~CAR;
  63.         a=(a<<1)|1; }
  64.     else {
  65.         if(a&128)flags|=CAR;
  66.         a=a<<1; }
  67.     FlagsNZ(a);
  68. }
  69. void i2c() { BIT(AbsoluteAddr); pc+=2; }
  70. void i2d() { AND(AbsoluteAddr); pc+=2; }
  71. void i2e() { ROL(AbsoluteAddr); pc+=2; }
  72. void i30() { BST(NEG); }
  73. void i31() { AND(IndirectYAddr); pc++; }
  74. void i35() { AND(ZeroPageXAddr); pc++; }
  75. void i36() { ROL(ZeroPageXAddr); pc++; }
  76. void i38() { SET(CAR); }
  77. void i39() { AND(AbsoluteYAddr); pc+=2; }
  78. void i3d() { AND(AbsoluteXAddr); pc+=2; }
  79. void i3e() { ROL(AbsoluteXAddr); pc+=2; }
  80. void i40() { flags=Pop(); PopWord(pc); }
  81. void i41() { EOR(IndirectXAddr); pc++; }
  82. void i45() { EOR(ZeroPageAddr); pc++; }
  83. void i46() { LSR(ZeroPageAddr); pc++; }
  84. void i48() { Push(a); }
  85. void i49() { a ^= ImmediateByte(); FlagsNZ(a); pc++; }
  86. void i4a() { 
  87.     flags &=~(CAR+NEG+ZER);
  88.     if (a&1) flags |=CAR;
  89.     if (a=a>>1); else flags |=ZER;
  90. }
  91. void i4c() { pc=WordAt(pc); }
  92. void i4d() { EOR(AbsoluteAddr); pc+=2; }
  93. void i4e() { LSR(AbsoluteAddr); pc+=2; }
  94. void i50() { BCL(OVF); }
  95. void i51() { EOR(IndirectYAddr); pc++; }
  96. void i55() { EOR(ZeroPageXAddr); pc++; }
  97. void i56() { LSR(ZeroPageXAddr); pc++; }
  98. void i58() { CLR(INT); }
  99. void i59() { EOR(AbsoluteYAddr); pc+=2; }
  100. void i5d() { EOR(AbsoluteXAddr); pc+=2; }
  101. void i5e() { LSR(AbsoluteXAddr); pc+=2; }
  102. void i60() { PopWord(pc); pc++; }
  103. void i61() { ADC(IndirectXAddr); pc++; }
  104. void i65() { ADC(ZeroPageAddr); pc++; }
  105. void i66() { ROR(ZeroPageAddr); pc++; }
  106. void i68() { a=Pop(); FlagsNZ(a); }
  107. void i69() {
  108.     register word data;
  109.     data=ImmediateByte();
  110.     if (flags&DEC) {
  111.         data = BCD2DEC(data)+BCD2DEC(a)+((flags&CAR)?1:0);
  112.         flags &= ~(CAR+OVF+NEG+ZER);
  113.         if (data>99) {
  114.             flags|=CAR+OVF;
  115.             data -=100; }
  116.         if (data==0) flags |= ZER;
  117.         else flags |= data&128;
  118.         DEC2BCD(data,a); }
  119.     else {
  120.         data += a+((flags&CAR)?1:0);
  121.         flags &= ~(CAR+OVF+NEG+ZER);
  122.         if (data>255) {
  123.             flags|=OVF+CAR;
  124.             data &=255; }
  125.         if (data==0) flags |= ZER;
  126.         else flags |= data&128;
  127.         a=data; }
  128.     pc++;
  129. }
  130. void i6a() {
  131.     if (flags&CAR) {
  132.         if ((a&1)==0) flags &=~CAR;
  133.         a=(a>>1)|128; }
  134.     else {
  135.         if(a&1) flags|=CAR;
  136.         a=a>>1; }
  137.     FlagsNZ(a);
  138. }
  139. void i6c() { register word ta; ta=WordAt(pc); pc=WordAt(ta); }
  140. void i6d() { ADC(AbsoluteAddr); pc+=2; }
  141. void i6e() { ROR(AbsoluteAddr); pc+=2; }
  142. void i70() { BST(OVF); }
  143. void i71() { ADC(IndirectYAddr); pc++; }
  144. void i75() { ADC(ZeroPageXAddr); pc++; }
  145. void i76() { ROR(ZeroPageXAddr); pc++; }
  146. void i78() { SET(INT); }
  147. void i79() { ADC(AbsoluteYAddr); pc+=2; }
  148. void i7d() { ADC(AbsoluteXAddr); pc+=2; }
  149. void i7e() { ROR(AbsoluteXAddr); pc+=2; }
  150. void i81() { STA(IndirectXAddr); pc++; }
  151. void i84() { STY(ZeroPageAddr); pc++; }
  152. void i85() { STA(ZeroPageAddr); pc++; }
  153. void i86() { STX(ZeroPageAddr); pc++; }
  154. void i88() { y--; FlagsNZ(y); }
  155. void i8a() { a=x; FlagsNZ(a); }
  156. void i8c() { STY(AbsoluteAddr); pc+=2; }
  157. void i8d() { STA(AbsoluteAddr); pc+=2; }
  158. void i8e() { STX(AbsoluteAddr); pc+=2; }
  159. void i90() { BCL(CAR); }
  160. void i91() { STA(IndirectYAddr); pc++; }
  161. void i94() { STY(ZeroPageXAddr); pc++; }
  162. void i95() { STA(ZeroPageXAddr); pc++; }
  163. void i96() { STX(ZeroPageYAddr); pc++; }
  164. void i98() { a=y; FlagsNZ(a); }
  165. void i99() { STA(AbsoluteYAddr); pc+=2; }
  166. void i9a() { sp=x; }
  167. void i9d() { STA(AbsoluteXAddr); pc+=2; }
  168. void ia0() { y=ImmediateByte(); FlagsNZ(y); pc++; }
  169. void ia1() { LDA(IndirectXAddr); pc++; }
  170. void ia2() { x=ImmediateByte(); FlagsNZ(x); pc++; }
  171. void ia4() { LDY(ZeroPageAddr); pc++; }
  172. void ia5() { LDA(ZeroPageAddr); pc++; }
  173. void ia6() { LDX(ZeroPageAddr); pc++; }
  174. void ia8() { y=a; FlagsNZ(y); }
  175. void ia9() { a=ImmediateByte(); FlagsNZ(a); pc++; }
  176. void iaa() { x=a; FlagsNZ(x); }
  177. void iac() { LDY(AbsoluteAddr); pc+=2; }
  178. void iad() { LDA(AbsoluteAddr); pc+=2; }
  179. void iae() { LDX(AbsoluteAddr); pc+=2; }
  180. void ib0() { BST(CAR); }
  181. void ib1() { LDA(IndirectYAddr); pc++; }
  182. void ib4() { LDY(ZeroPageXAddr); pc++; }
  183. void ib5() { LDA(ZeroPageXAddr); pc++; }
  184. void ib6() { LDX(ZeroPageYAddr); pc++; }
  185. void ib8() { CLR(OVF); }
  186. void ib9() { LDA(AbsoluteYAddr); pc+=2; }
  187. void iba() { x=sp; }
  188. void ibc() { LDY(AbsoluteXAddr); pc+=2; }
  189. void ibd() { LDA(AbsoluteXAddr); pc+=2; }
  190. void ibe() { LDX(AbsoluteYAddr); pc+=2; }
  191. void ic0() {
  192.     register byte tbyte;
  193.     tbyte=ImmediateByte();
  194.     flags &=~(CAR+ZER+NEG);
  195.     if (y==tbyte) flags |=CAR+ZER;
  196.     else if (y>tbyte) flags |=CAR;
  197.     else flags |=NEG;
  198.     pc++;
  199. }
  200. void ic1() { CMP(IndirectXAddr); pc++; }
  201. void ic4() { CPY(ZeroPageAddr); pc++; }
  202. void ic5() { CMP(ZeroPageAddr); pc++; }
  203. void ic6() { DECR(ZeroPageAddr); pc++; }
  204. void ic8() { y++; FlagsNZ(y); }
  205. void ic9() {
  206.     register byte tbyte;
  207.     tbyte=ImmediateByte();
  208.     flags &=~(CAR+ZER+NEG);
  209.     if (a==tbyte) flags |=CAR+ZER;
  210.     else if (a>tbyte) flags |=CAR;
  211.         else flags |=NEG;
  212.     pc++;
  213. }
  214. void ica() { x--; FlagsNZ(x); }
  215. void icc() { CPY(AbsoluteAddr); pc+=2; }
  216. void icd() { CMP(AbsoluteAddr); pc+=2; }
  217. void ice() { DECR(AbsoluteAddr); pc+=2; }
  218. void id0() { BCL(ZER); }
  219. void id1() { CMP(IndirectYAddr); pc++; }
  220. void id5() { CMP(ZeroPageXAddr); pc++; }
  221. void id6() { DECR(ZeroPageXAddr); pc++; }
  222. void id8() { CLR(DEC); }
  223. void id9() { CMP(AbsoluteYAddr); pc+=2; }
  224. void idd() { CMP(AbsoluteXAddr); pc+=2; }
  225. void ide() { DECR(AbsoluteXAddr); pc+=2; }
  226. void ie0() {
  227.     register byte tbyte;
  228.     tbyte=ImmediateByte();
  229.     flags &=~(CAR+ZER+NEG);
  230.     if (x==tbyte) flags |=CAR+ZER;
  231.     else if (x>tbyte) flags |=CAR;
  232.     else flags |=NEG;
  233.     pc++;
  234. }
  235. void ie1() { SBC(IndirectXAddr); pc++; }
  236. void ie4() { CPX(ZeroPageAddr); pc++; }
  237. void ie5() { SBC(ZeroPageAddr); pc++; }
  238. void ie6() { INCR(ZeroPageAddr); pc++; }
  239. void ie8() { x++; FlagsNZ(x); }
  240. void ie9() {
  241.     register int data;
  242.     data=ImmediateByte();
  243.     if (flags&DEC) {
  244.         data = BCD2DEC(a)-BCD2DEC(data)-((flags&CAR)?0:1);
  245.         flags &= ~(CAR+ZER+NEG+OVF);
  246.         if (data==0) flags |=ZER+CAR;
  247.         else if (data>0) flags |=CAR;
  248.             else {
  249.                 flags|=NEG;
  250.                 data +=100; }
  251.         DEC2BCD(data,a); }
  252.     else {
  253.         data = a-data-((flags&CAR)?0:1);
  254.         flags &=~(CAR+ZER+OVF+NEG);
  255.         if (data==0) flags |= ZER+CAR;
  256.         else if (data>0) flags |= CAR;
  257.             else flags|=OVF;
  258.         data &= 255;
  259.         flags |= data&128;
  260.         a=data; }
  261.     pc++; 
  262. }
  263. void iea() {}
  264. void iec() { CPX(AbsoluteAddr); pc+=2; }
  265. void ied() { SBC(AbsoluteAddr); pc+=2; }
  266. void iee() { INCR(AbsoluteAddr); pc+=2; }
  267. void if0() { BST(ZER); }
  268. void if1() { SBC(IndirectYAddr); pc++; }
  269. void if5() { SBC(ZeroPageXAddr); pc++; }
  270. void if6() { INCR(ZeroPageXAddr); pc++; }
  271. void if8() { SET(DEC); }
  272. void if9() { SBC(AbsoluteYAddr); pc+=2; }
  273. void ifd() { SBC(AbsoluteXAddr); pc+=2; }
  274. void ife() { INCR(AbsoluteXAddr); pc+=2; }
  275. void iff() { TrapExecute(); }
  276.  
  277. void ini() {
  278. #ifdef MACSBUG
  279. DebugStr("\pNonImplemented!");
  280. #endif
  281. pc+=2;}
  282.  
  283. void InstructionInitialize()
  284. { }
  285.  
  286. void (* instruct[256]) () = {
  287.     i00, i01, ini, ini, ini, i05, i06, ini,
  288.     i08, i09, i0a, ini, ini, i0d, i0e, ini,
  289.     i10, i11, ini, ini, ini, i15, i16, ini,
  290.     i18, i19, ini, ini, ini, i1d, i1e, ini,
  291.     i20, i21, ini, ini, i24, i25, i26, ini,
  292.     i28, i29, i2a, ini, i2c, i2d, i2e, ini,
  293.     i30, i31, ini, ini, ini, i35, i36, ini,
  294.     i38, i39, ini, ini, ini, i3d, i3e, ini,
  295.     i40, i41, ini, ini, ini, i45, i46, ini,
  296.     i48, i49, i4a, ini, i4c, i4d, i4e, ini,
  297.     i50, i51, ini, ini, ini, i55, i56, ini,
  298.     i58, i59, ini, ini, ini, i5d, i5e, ini,
  299.     i60, i61, ini, ini, ini, i65, i66, ini,
  300.     i68, i69, i6a, ini, i6c, i6d, i6e, ini,
  301.     i70, i71, ini, ini, ini, i75, i76, ini,
  302.     i78, i79, ini, ini, ini, i7d, i7e, ini,
  303.     ini, i81, ini, ini, i84, i85, i86, ini,
  304.     i88, ini, i8a, ini, i8c, i8d, i8e, ini,
  305.     i90, i91, ini, ini, i94, i95, i96, ini,
  306.     i98, i99, i9a, ini, ini, i9d, ini, ini,
  307.     ia0, ia1, ia2, ini, ia4, ia5, ia6, ini,
  308.     ia8, ia9, iaa, ini, iac, iad, iae, ini,
  309.     ib0, ib1, ini, ini, ib4, ib5, ib6, ini,
  310.     ib8, ib9, iba, ini, ibc, ibd, ibe, ini,
  311.     ic0, ic1, ini, ini, ic4, ic5, ic6, ini,
  312.     ic8, ic9, ica, ini, icc, icd, ice, ini,
  313.     id0, id1, ini, ini, ini, id5, id6, ini,
  314.     id8, id9, ini, ini, ini, idd, ide, ini,
  315.     ie0, ie1, ini, ini, ie4, ie5, ie6, ini,
  316.     ie8, ie9, iea, ini, iec, ied, iee, ini,
  317.     if0, if1, ini, ini, ini, if5, if6, ini,
  318.     if8, if9, ini, ini, ini, ifd, ife, iff};
  319.  
  320. byte cycletime[256]={
  321. /*00*/    7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
  322. /*10*/    3, 5, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  323. /*20*/    6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
  324. /*30*/    3, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
  325. /*40*/    6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
  326. /*50*/    3, 6, 0, 0, 0, 3, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  327. /*60*/    6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
  328. /*70*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  329. /*80*/    0, 6, 0, 0, 6, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
  330. /*90*/    2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
  331. /*A0*/    2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
  332. /*B0*/    3, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 5, 5, 5, 0,
  333. /*C0*/    2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
  334. /*D0*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  335. /*E0*/    2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
  336. /*F0*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 1 };
  337.  
  338.